// 1. bottomVisible：检查页面底部是否可见
const bottomVisible = () =>
	document.documentElement.clientHeight + window.scrollY >=
	(document.documentElement.scrollHeight || document.documentElement.clientHeight);

bottomVisible(); // true

// 2. currentURL：返回当前链接url
const currentURL = () => window.location.href;

currentURL(); // 'https://juejin.cn'

// 3. elementContains：检查是否包含子元素
const elementContains = (parent, child) => parent !== child && parent.contains(child);

elementContains(document.querySelector('head'), document.querySelector('title')); // true
elementContains(document.querySelector('body'), document.querySelector('body')); // false

// 4. getStyle：返回指定元素的生效样式
const getStyle = (el, ruleName) => getComputedStyle(el)[ruleName];

getStyle(document.querySelector('p'), 'font-size'); // '16px'

// 5. hasClass：校验指定元素的类名
const hasClass = (el, className) => el.classList.contains(className);
hasClass(document.querySelector('p.special'), 'special'); // true

// 6. httpsRedirect：HTTP 跳转 HTTPS
const httpsRedirect = () => {
	if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]);
};

httpsRedirect(); // 若在`http://www.baidu.com`, 则跳转到`https://www.baidu.com`

// 7. insertAfter：在指定元素之后插入新元素
const insertAfter = (el, htmlString) => el.insertAdjacentHTML('afterend', htmlString);
// <div id="myId">...</div> <p>after</p>
insertAfter(document.getElementById('myId'), '<p>after</p>');

// 8. insertBefore：在指定元素之前插入新元素
const insertBefore = (el, htmlString) => el.insertAdjacentHTML('beforebegin', htmlString);
insertBefore(document.getElementById('myId'), '<p>before</p>'); // <p>before</p> <div id="myId">...</div>

// 9. isBrowser：检查是否为浏览器环境
// 此代码段可用于确定当前运行时环境是否为浏览器。这有助于避免在服务器（节点）上运行前端模块时出错。
const isBrowser = () => ![ typeof window, typeof document ].includes('undefined');

isBrowser(); // true (browser)
isBrowser(); // false (Node)

// 10 scrollToTop：平滑滚动至顶部
const scrollToTop = () => {
	const c = document.documentElement.scrollTop || document.body.scrollTop;
	if (c > 0) {
		window.requestAnimationFrame(scrollToTop);
		window.scrollTo(0, c - c / 8);
	}
};

scrollToTop();

// 11. smoothScroll：滚动到指定元素区域
// 该代码段可将指定元素平滑滚动到浏览器窗口的可见区域。
const smoothScroll = (element) =>
	document.querySelector(element).scrollIntoView({
		behavior: 'smooth'
	});

smoothScroll('#fooBar');
smoothScroll('.fooBar');

// 12. detectDeviceType：检测移动/PC设备
const detectDeviceType = () =>
	/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ? 'Mobile' : 'Desktop';

// 13. getScrollPosition：返回当前的滚动位置
// 默认参数为window ，pageXOffset(pageYOffset)为第一选择，没有则用scrollLeft(scrollTop)
const getScrollPosition = (el = window) => ({
	x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
	y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});

getScrollPosition(); // {x: 0, y: 200}

// 14. size：获取不同类型变量的字节长度
const size = (val) =>
	Array.isArray(val)
		? val.length
		: val && typeof val === 'object'
			? val.size || val.length || Object.keys(val).length
			: typeof val === 'string' ? new Blob([ val ]).size : 0;

size([ 1, 2, 3, 4, 5 ]); // 5
size('size'); // 4
size({ one: 1, two: 2, three: 3 }); // 3

// 15. escapeHTML：转义HTML
const escapeHTML = (str) =>
	str.replace(
		/[&<>'"]/g,
		(tag) =>
			({
				'&': '&amp;',
				'<': '&lt;',
				'>': '&gt;',
				"'": '&#39;',
				'"': '&quot;'
			}[tag] || tag)
	);

escapeHTML('<a href="#">Me & you</a>'); // '&lt;a href=&quot;#&quot;&gt;Me &amp; you&lt;/a&gt;'
